#ifndef HTTP_PROTOCOL_PARSE_H
#define HTTP_PROTOCOL_PARSE_H

#include "http_object.h"

namespace HttpFrame
{


struct ConnInfor_t
{
    int fd_;
    int type_;
    unsigned int localip_;
    unsigned int remoteip_;
    unsigned short localport_;
    unsigned short remoteport_;

    ConnInfor_t()
    {
       fd_=-1;
       type_=-1;
       localip_=0;
       remoteip_=0;
       localport_=0;
       remoteport_=0;
    }
};

/*
class CHttpProtocolReadler
{
public:
    virtual ~CHttpProtocolReadler(){}
    virtual int GetBodyLen()=0;
    virtual void* GetBody()=0;
    virtual int GetPara(const char* pszParaName, char *pszValue,int nValueSize)=0;
    virtual void AddExtPara(const char* pszParaName, const char *pszValue)=0;
};

class CHttpProtocolWriter
{
public:
    virtual ~CHttpProtocolWriter(){}
    
    virtual void AddExtPara(const char* pszParaName, const char *pszValue)=0;
    
    virtual int MakeRequest(int nVersion
		                                  ,int nCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen)=0;

    virtual int MakeRequest(const char *pszVersion
		                                  ,const char *pszCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen)=0;

    virtual int MakeRespone(int nRetCode
		                                  ,char *pszRetDesc
		                                  ,int nVersion
		                                  ,int nCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen)=0;

    virtual int MakeRespone(int nRetCode
		                                  ,char *pszRetDesc
		                                  ,const char *pszVersion
		                                  ,const char *pszCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen)=0;
    
};
*/

class CHttpProtocolParse
{
public:
	static int GetPara(const char* pszContent, const char* pszParaName, char *pszValue,int nValueSize); 
	static int ParseValue(const char* pszValue, int iMaxNum, int* piNum,unsigned int auiValue[]);
	static int GetBodyLen(const char *pszContent);
	static char* GetBody(const char *pszContent);
	static int GetHeadLen(const char *pszContent);
	static int GetLen(const char *pszContent);
	static bool IsPackOk(const char *pszContent,int nLen);
       static char* StrTrim(char *pszSrc);
	/*
	static int MakeRequestHeader(char *pszBuffer,int iBuffSize
		                                  ,int nVersion
		                                  ,int nCmd
		                                  ,const char *pszAbstract
		                                  ,int nBodyLen
		                                  ,const char *pszClientVersion="");

	static int MakeResponeHeader(char *pszBuffer,int iBuffSize
		                                  ,int nRetCode
		                                  ,char *pszRetDesc
		                                  ,int nVersion
		                                  ,int nCmd
		                                  ,const char *pszAbstract
		                                  ,int nBodyLen
		                                  ,const char *pszServerVersion="");
	*/
public:
    CHttpProtocolParse(char *pszData,unsigned int nBufLen
		,const char *pszCmdName="X_CMD"
		,const char* pszVersionName="X_VERSION"
		,const char* pszClientName="HttpFrameClient"
		,const char* pszServerName="HttpFrameServer");
	
     virtual ~CHttpProtocolParse();
    int      SetPack(void *pPack,unsigned int nPackLen);
      	
    void* GetData() { return m_pszData; }
    unsigned int GetBufLen() { return m_nBufLen; }
    
    virtual unsigned int GetPackLen() { return m_nPackLen; }
    virtual int GetBodyLen(){ return CHttpProtocolParse::GetBodyLen(m_pszData);}
    virtual void* GetBody(){return (void*)CHttpProtocolParse::GetBody(m_pszData);}
    virtual int GetHeadLen(){return CHttpProtocolParse::GetHeadLen(m_pszData);}
    virtual int GetPara(const char* pszParaName, char *pszValue,int nValueSize);
    virtual int GetPara(const char* pszParaName, int &nValue);
    virtual int GetPara(const char* pszParaName, long &lValue);
    virtual int GetPara(const char* pszParaName, unsigned int &unValue);
    virtual int GetPara(const char* pszParaName, unsigned long &ulValue);
    virtual int GetPara(const char* pszParaName, char &cValue);
    virtual int GetPara(const char* pszParaName, unsigned char &ucValue);
    
    virtual int GetEnv(const char* pszParaName, char *pszValue,int nValueSize);
    virtual int GetEnv(const char* pszParaName, int &iValue);
    virtual int GetEnv(const char* pszParaName, long &lValue);
    virtual int GetEnv(const char* pszParaName, unsigned int &unValue);
    virtual int GetEnv(const char* pszParaName, unsigned long &ulValue);
    virtual int GetEnv(const char* pszParaName, char &cValue);
    virtual int GetEnv(const char* pszParaName, unsigned char &ucValue);
 
    
    virtual void AddExtPara(const char* pszParaName, const char *pszValue);
    virtual void AddExtPara(const char* pszParaName, int nValue);
    virtual void AddExtPara(const char* pszParaName, long lValue);
    virtual void AddExtPara(const char* pszParaName, unsigned int unValue);
    virtual void AddExtPara(const char* pszParaName, unsigned long ulValue);
    virtual void AddExtPara(const char* pszParaName, char cValue);
    virtual void AddExtPara(const char* pszParaName, unsigned char ucValue);
    

    int MakeRequest(int nVersion
		                                  ,int nCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen);

    int MakeRespone(int nRetCode
		                                  ,char *pszRetDesc
		                                  ,int nVersion
		                                  ,int nCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen);
	
    int MakeRequest(const char *pszVersion
		                                  ,const char *pszCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen);

    int MakeRespone(int nRetCode
		                                  ,char *pszRetDesc
		                                  ,const char *pszVersion
		                                  ,const char *pszCmd
		                                  ,void *pBody
		                                  ,unsigned int nBodyLen);
	
    const char* CmdName(){ return m_szCmdName; }

    const char* VersionName(){ return m_szVersionName; }

    const char* ClientName(){ return m_szClientName; }

    const char* ServerName(){ return m_szServerName; }

    ConnInfor_t* ConnInfo(ConnInfor_t* pConnInfo) { m_pConnInf=pConnInfo; return m_pConnInf;}
    ConnInfor_t* ConnInfo() { return m_pConnInf;}
    	

    int ConnFd();
    int ConnType();
    unsigned int ConnLocalIp();
    unsigned int ConnRemoteIp();
    unsigned short ConnLocalPort();
    unsigned short ConnRemotePort();
    
protected:
    CHttpProtocolParse();
	
protected:
    char* m_pszData;
    unsigned int m_nBufLen;
    unsigned int m_nPackLen;
    unsigned int m_nExtHeadLen;
    char    m_szExtHeadBuffer[1024*100];
         
    char           m_szCmdName[255];
    char           m_szVersionName[255];
    char           m_szClientName[255];
    char           m_szServerName[255];

    ConnInfor_t            *m_pConnInf; 
};



class CStreamHttpProtocolParse:public CHttpProtocolParse
{
public:
	
public:
	CStreamHttpProtocolParse(char *pszData,unsigned int nBufLen
		,const char *pszCmdName="X_CMD"
		,const char* pszVersionName="X_VERSION"
		,const char* pszClientName="HttpFrameClient"
		,const char* pszServerName="HttpFrameServer");
	
      virtual ~CStreamHttpProtocolParse(){}
      
	
	//virtual int GetBodyLen(){ return CHttpProtocolParse::GetBodyLen(m_pszData);}
	//virtual char* GetBody(){return CHttpProtocolParse::GetBody(m_pszData);}
	//virtual int GetHeadLen(){return CHttpProtocolParse::GetHeadLen(m_pszData);}
	
	//virtual int GetPara(const char* pszParaName, char *pszValue,int nValueSize){return CHttpProtocolParse::GetPara(m_pszData,pszParaName,pszValue,nValueSize);}
	
};



class CCgiHttpProtocolParse:public CHttpProtocolParse
{
public:
	
public:
	CCgiHttpProtocolParse(char *pszData,unsigned int nBufLen
		,const char *pszCmdName="X_CMD"
		,const char* pszVersionName="X_VERSION"
		,const char* pszClientName="HttpFrameClient"
		,const char* pszServerName="HttpFrameServer");
	
      virtual ~CCgiHttpProtocolParse(){}
      
	
	virtual int GetBodyLen();
	virtual void* GetBody();

	virtual int ReadBody();
	
	virtual int GetPara(const char* pszParaName, char *pszValue,int nValueSize);
	virtual int GetEnv(const char* pszParaName, char *pszValue,int nValueSize);
	
};

class CAsynCgiHttpProtocolParse:public CCgiHttpProtocolParse
{

public:
	CAsynCgiHttpProtocolParse(char *pszData,unsigned int nBufLen
		,CHttpObject* phttp_object
		,const char *pszCmdName="X_CMD"
		,const char* pszVersionName="X_VERSION"
		,const char* pszClientName="HttpFrameClient"
		,const char* pszServerName="HttpFrameServer"
		);
	
      virtual ~CAsynCgiHttpProtocolParse(){}
      
	
	virtual int GetBodyLen();

	virtual int ReadBody();
	
	virtual int GetPara(const char* pszParaName, char *pszValue,int nValueSize);
	virtual int GetEnv(const char* pszParaName, char *pszValue,int nValueSize);

protected:

	CHttpObject* m_phttp_object;
	
};

}

#endif
